﻿using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Input;
using XNAFight.Scene.Core;
using XNAFight.Characters;
using XNAFight.Characters.Core;
using XNAFight.Engine;
using XNAFight.Engine.Inputs;
using System;
using System.Diagnostics;
using System.Collections.Generic;
using XNAFight.Scene.SandBoxOne;



namespace XNAFight.Scene.ToolAnime
{
    class ToolAnime : Screen
    {
        #region CHAMPS

        private bool paused;
        private List<GameObject> gameObjects;
        private Character perso_one, perso_two;

        private SandBoxOneMenu menu;
        private ToolAnimeDebugOne debug_one;
                
        private AnimationData anime_de_base;
        private AnimationData anime_en_cours_de_modif;
        private float new_vitesse_anime;
        private float pas;

        #endregion

        #region PROPRIETES

        public List<GameObject> GameObjects
        {
            get { return gameObjects; }

        }

        #endregion

        #region CONSTRUCTEUR

        public ToolAnime(string _charname):base()
        {
            paused = false;

            gameObjects = new List<GameObject>();

            perso_one = getCharacterFromName(CommonContent.CurrentGame.Content, _charname, new Vector2(200, 300));
            perso_two = getCharacterFromName(CommonContent.CurrentGame.Content, _charname, new Vector2(600, 300));

            GameObjects.Add(perso_one);
            GameObjects.Add(perso_two);

            anime_de_base = new AnimationData();
            anime_de_base.setFrom(perso_one.getAnimationData_from_AnimationName(perso_one.AnimationEnCours));
            anime_en_cours_de_modif = new AnimationData();
            anime_en_cours_de_modif.setFrom(anime_de_base);

            new_vitesse_anime = anime_de_base.FrameParSec;
            pas = 0.5f;
            
            menu = new SandBoxOneMenu("Pause");
            menu.Adding += pause;
            menu.Cancelled += unpause;

            menu.Completed += leaveInGame;

            debug_one = new ToolAnimeDebugOne(perso_one, anime_en_cours_de_modif, pas);

            this.Added += this.Activate;
            this.Removed += debug_one.Complete;
            this.Removed += this.Disable;        
        }

        #endregion

        #region LOAD, DRAW, UPDATE

        protected override void LoadContent()
        {
            base.LoadContent();

            foreach (GameObject _gameObject in gameObjects)
            {
                _gameObject.Load();
            }
        }

        public override void Update(GameTime _game_time)
        {
            if (paused)
                return;

            base.Update(_game_time);

            if(new_vitesse_anime != anime_en_cours_de_modif.FrameParSec)
            {
                anime_en_cours_de_modif.FrameParSec = new_vitesse_anime;
                relance_anime();                
            }

            float elapsed = (float)_game_time.ElapsedGameTime.TotalSeconds;

            /*foreach (GameObject _gameObject in gameObjects)
            {
                _gameObject.Update(elapsed);
            }*/

            perso_one.Sprite.updateFrame(elapsed);
            perso_two.Sprite.updateFrame(elapsed);
        }

        public override void Draw(GameTime gameTime)
        {
            base.Draw(gameTime);

            CommonContent.SpriteBatch.Begin();

            // La boucle qui va afficher tous les éléments du jeu (à insérer lors de leur création dans la liste GameObjects
            foreach (GameObject _gameObject in GameObjects)
            {
                if (_gameObject.Alive)
                {
                    _gameObject.draw(CommonContent.SpriteBatch);
                }
            }

            CommonContent.SpriteBatch.End();
        }

        #endregion

        #region AUTRES METHODES

        private Character getCharacterFromName(ContentManager _ContentManager, string _name, Vector2 _pos_depart)
        {
            Character character = null;

            switch (_name)
            {
                case "Ryu": character = new Ryu(_ContentManager, _pos_depart);
                    break;
                case "Guile": character = new Guile(_ContentManager, _pos_depart);
                    break;
                case "Zangief": character = new Zangief(_ContentManager, _pos_depart);
                    break;
            }


            return character;
        }

        public override void HandleInputs()
        {
            if (MenuInputInterpreter.isMenuCanceled())
            {
                //buffer_viewer.Remove();
                menu.Add();
            }
            if (MenuInputInterpreter.isDebugPressed())
            {
                if (debug_one.IsAlive)
                    debug_one.Cancel();
                else
                    debug_one.Add();                
            }

            if (InputState.isNewKeyPressed(Keys.Left))
            {
                new_vitesse_anime -= pas;
            }
            if (InputState.isNewKeyPressed(Keys.Right))
            {
                new_vitesse_anime += pas;
            }
            if (InputState.isNewKeyPressed(Keys.Up))
            {
                pas += 0.1f;
                debug_one.Pas = pas;
            }
            if (InputState.isNewKeyPressed(Keys.Down))
            {
                pas -= 0.1f;
                if (pas <= 0.1f)
                    pas = 0.1f;
                debug_one.Pas = pas;
            }
            if (InputState.isNewKeyPressed(Keys.R))
            {
                reset_anime();
            }
            if (InputState.isNewKeyPressed(Keys.PageDown))
            {
                string nomNextAnime = getNomAnimeSuivante();
                if (nomNextAnime != anime_en_cours_de_modif.NomAnimation)
                {
                    nouvelle_anime(nomNextAnime);
                }
            }
            if (InputState.isNewKeyPressed(Keys.PageUp))
            {
                string nomPrevAnime = getNomAnimePrecedente();
                if (nomPrevAnime != anime_en_cours_de_modif.NomAnimation)
                {
                    nouvelle_anime(nomPrevAnime);
                }
            }
        }

        public void pause()
        {
            paused = true;
        }
        public void pause(object _sender, EventArgs _e)
        {
            pause();
        }
        public void unpause()
        {
            paused = false;
        }
        public void unpause(object _sender, EventArgs _e)
        {
            unpause();
        }
                
        private void reset_anime()
        {
            anime_en_cours_de_modif.setFrom(anime_de_base);
            new_vitesse_anime = anime_de_base.FrameParSec;
            relance_anime();
        }
        
        private void relance_anime()
        {
            if (anime_en_cours_de_modif.SensInverse)
                perso_one.Sprite.animSimple(anime_en_cours_de_modif.EndingFrame, anime_en_cours_de_modif.StartingFrame, anime_en_cours_de_modif.TempsAnime, anime_en_cours_de_modif.Loop, anime_en_cours_de_modif.SensInverse);
            else
                perso_one.Sprite.animSimple(anime_en_cours_de_modif.StartingFrame, anime_en_cours_de_modif.EndingFrame, anime_en_cours_de_modif.TempsAnime, anime_en_cours_de_modif.Loop, anime_en_cours_de_modif.SensInverse);
            

            
        }

        private void nouvelle_anime(string anime_name)
        {
            perso_one.anime(anime_name);
            anime_de_base.setFrom(perso_one.getAnimationData_from_AnimationName(anime_name));
            anime_en_cours_de_modif.setFrom(anime_de_base);

            new_vitesse_anime = anime_en_cours_de_modif.FrameParSec;
        }
        
        private string getNomAnimeSuivante()
        {
            if (perso_one.AnimationList.Count != 1)
            {
                bool isNextAnime = false;
                
                foreach (AnimationData _anime in perso_one.AnimationList)
                {
                    if (isNextAnime)
                    {
                        return _anime.NomAnimation;
                    }
                    
                    if (anime_en_cours_de_modif.NomAnimation == _anime.NomAnimation)
                    {
                        isNextAnime = true;
                    }
                }
            }

            return anime_en_cours_de_modif.NomAnimation;
        }
        
        private string getNomAnimePrecedente()
        {
            if (perso_one.AnimationList.Count != 1)
            {
                AnimationData anime_prev;
                anime_prev = anime_en_cours_de_modif;
                
                foreach (AnimationData _anime in perso_one.AnimationList)
                {
                    if (_anime.NomAnimation == anime_en_cours_de_modif.NomAnimation)
                    {
                        return anime_prev.NomAnimation;
                    }
                    anime_prev = _anime;
                    
                }
            }

            return anime_en_cours_de_modif.NomAnimation;
        }
        
        public override void Reset()
        {
            base.Reset();
        }

        private void leaveInGame()
        {
            Game game = this.Game;
            complete = true;
            Remove();
            Program.CreateMainMenu();
        }
        private void leaveInGame(object _sender, EventArgs _e)
        {
            leaveInGame();
        }
        
        #endregion

    }
}
